#include "mqtt_file_transfer.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>

// 生成文件ID
char *generate_file_id(void) {
    static char file_id[37];
    const char *chars = "0123456789abcdef";

    srand(time(NULL));
    for (int i = 0; i < 36; i++) {
        if (i == 8 || i == 13 || i == 18 || i == 23) {
            file_id[i] = '-';
        } else {
            file_id[i] = chars[rand() % 16];
        }
    }
    file_id[36] = '\0';

    return file_id;
}

// 获取文件大小
size_t get_file_size(const char *filename) {
    struct stat st;
    if (stat(filename, &st) == 0) {
        return st.st_size;
    }
    return 0;
}

// Base64编码
char *base64_encode(const uint8_t *data, size_t input_length) {
    const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    size_t output_length = 4 * ((input_length + 2) / 3);
    char *encoded_data = malloc(output_length + 1);
    if (!encoded_data) return NULL;

    for (size_t i = 0, j = 0; i < input_length;) {
        uint32_t octet_a = i < input_length ? data[i++] : 0;
        uint32_t octet_b = i < input_length ? data[i++] : 0;
        uint32_t octet_c = i < input_length ? data[i++] : 0;

        uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;

        encoded_data[j++] = base64_chars[(triple >> 3 * 6) & 0x3F];
        encoded_data[j++] = base64_chars[(triple >> 2 * 6) & 0x3F];
        encoded_data[j++] = base64_chars[(triple >> 1 * 6) & 0x3F];
        encoded_data[j++] = base64_chars[(triple >> 0 * 6) & 0x3F];
    }

    // 添加填充字符
    for (size_t i = 0; i < (3 - input_length % 3) % 3; i++) {
        encoded_data[output_length - 1 - i] = '=';
    }

    encoded_data[output_length] = '\0';
    return encoded_data;
}
uint8_t *base64_decode(const char *data, size_t input_length, size_t *output_length) {
    static const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    if (input_length % 4 != 0) {
        return NULL;
    }

    *output_length = input_length / 4 * 3;
    if (data[input_length - 1] == '=') (*output_length)--;
    if (data[input_length - 2] == '=') (*output_length)--;

    uint8_t *decoded_data = malloc(*output_length);
    if (!decoded_data) return NULL;

    for (size_t i = 0, j = 0; i < input_length;) {
        uint32_t sextet_a, sextet_b, sextet_c, sextet_d;

        // 处理第一个字符
        if (data[i] == '=') {
            sextet_a = 0;
            i++;
        } else {
            char *pos = strchr(base64_chars, data[i++]);
            if (!pos) {
                free(decoded_data);
                return NULL;
            }
            sextet_a = (uint32_t)(pos - base64_chars);
        }

        // 处理第二个字符
        if (data[i] == '=') {
            sextet_b = 0;
            i++;
        } else {
            char *pos = strchr(base64_chars, data[i++]);
            if (!pos) {
                free(decoded_data);
                return NULL;
            }
            sextet_b = (uint32_t)(pos - base64_chars);
        }

        // 处理第三个字符
        if (data[i] == '=') {
            sextet_c = 0;
            i++;
        } else {
            char *pos = strchr(base64_chars, data[i++]);
            if (!pos) {
                free(decoded_data);
                return NULL;
            }
            sextet_c = (uint32_t)(pos - base64_chars);
        }

        // 处理第四个字符
        if (data[i] == '=') {
            sextet_d = 0;
            i++;
        } else {
            char *pos = strchr(base64_chars, data[i++]);
            if (!pos) {
                free(decoded_data);
                return NULL;
            }
            sextet_d = (uint32_t)(pos - base64_chars);
        }

        uint32_t triple = (sextet_a << 18) + (sextet_b << 12) + (sextet_c << 6) + sextet_d;

        if (j < *output_length) decoded_data[j++] = (triple >> 16) & 0xFF;
        if (j < *output_length) decoded_data[j++] = (triple >> 8) & 0xFF;
        if (j < *output_length) decoded_data[j++] = triple & 0xFF;
    }

    return decoded_data;
}
// Base64解码
// uint8_t *base64_decode(const char *data, size_t input_length, size_t *output_length) {
//     const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

//     if (input_length % 4 != 0) {
//         return NULL;
//     }

//     *output_length = input_length / 4 * 3;
//     if (data[input_length - 1] == '=') (*output_length)--;
//     if (data[input_length - 2] == '=') (*output_length)--;

//     uint8_t *decoded_data = malloc(*output_length);
//     if (!decoded_data) return NULL;

//     for (size_t i = 0, j = 0; i < input_length;) {
//         uint32_t sextet_a = data[i] == '=' ? 0 & i++ : strchr(base64_chars, data[i++]) - base64_chars;
//         uint32_t sextet_b = data[i] == '=' ? 0 & i++ : strchr(base64_chars, data[i++]) - base64_chars;
//         uint32_t sextet_c = data[i] == '=' ? 0 & i++ : strchr(base64_chars, data[i++]) - base64_chars;
//         uint32_t sextet_d = data[i] == '=' ? 0 & i++ : strchr(base64_chars, data[i++]) - base64_chars;

//         uint32_t triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6) + (sextet_c << 1 * 6) + (sextet_d << 0 * 6);

//         if (j < *output_length) decoded_data[j++] = (triple >> 2 * 8) & 0xFF;
//         if (j < *output_length) decoded_data[j++] = (triple >> 1 * 8) & 0xFF;
//         if (j < *output_length) decoded_data[j++] = (triple >> 0 * 8) & 0xFF;
//     }

//     return decoded_data;
// }
